/*
 * start.S
 *
 */

#include <my_linkage.h>
#include <riscv64.h>

	.global _start
_start:
	/* Boot head information for BROM */
	.long 0x0300006f
	.byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0'
	.long 0x12345678				/* checksum */
	.long __spl_size				/* spl size */
	.long 0x30						/* boot header size */
	.long 0x30303033				/* boot header version */
	.long 0x00020000				/* return value */
	.long 0x00020000				/* run address */
	.long 0x0						/* eGON version */
	.byte 0x00, 0x00, 0x00, 0x00	/* platform information - 8byte */
	.byte 0x34, 0x2e, 0x30, 0x00

/*
 * The actual reset code
 */
reset:
	/* Mask all interrupts */
	csrw mideleg, zero
	csrw medeleg, zero
	csrw mie, zero
	csrw mip, zero

	/* Setup exception vectors */
	 la t1, _image_start
	 LREG t1, (t1)
	 la t2, _start
	 sub t0, t1, t2
	 la a0, vectors
	 add a0, a0, t0
	 csrw mtvec, a0

	/* Enable FPU and accelerator if present */
	li t0, MSTATUS_FS | MSTATUS_XS
	csrs mstatus, t0

	/* Enable theadisaee */
	li t1, 0x1 << 22
	.word 0x7c032073	/* csrs mxstatus, t1 */

	/* Invaild icache/dcache/btb/bht */
	li t1, 0x30013
	.word 0x7c232073	/* csrs mcor, t1 */

	/* Check processor id and initialized */
	csrr t0, mhartid
	bnez t0, _avoid
	la t0, _start
	la t1, _image_start
	LREG t1, (t1)
	beq t0, t1, _avoid

	/* Initial system jtag, uart and clock */
	/*call sys_jtag_init*/
	call sys_uart_init
	call sys_clock_init

	/* Copy ddr bin to 0x00030000 */
	la t1, _ddr_bin_start
	LREG t1, (t1)
	la t2, _ddr_bin_end
	LREG t2, (t2)
	sub a2, t2, t1
	la t1, _image_start
	LREG t1, (t1)
	la t2, _ddr_bin_start
	LREG t2, (t2)
	sub t0, t2, t1
	la a1, _start
	add a1, a1, t0
	li a0, 0x00030000
	call my_memcpy

	/* Initial ddr controller */
	call sys_dram_init
_avoid:
	nop

	/* Initialize global pointer */
.option push
.option norelax
	la t0, _global_pointer$
	LREG gp, (t0)
.option pop

	/* Initialize stacks */
	la t1, _stack_start
	LREG t1, (t1)
	la t2, _stack_end
	LREG t2, (t2)
	sub t0, t2, t1
	csrr t3, mhartid
	li t4, 1
	div t0, t0, t4
	mul t0, t0, t3
	sub sp, t2, t0

	/* Check processor id, and startup slave cores */
	csrr a0, mhartid
	beqz a0, 2f
1:	nop
	j 1b
2:	nop

	/* Copyself to link address */
	la t0, _start
	la t1, _image_start
	LREG t1, (t1)
	beq t0, t1, 1f
	call sys_copyself
1:	nop

	/* Clear bss section */
	 la a0, _bss_start
	 LREG a0, (a0)
	 la a2, _bss_end
	 LREG a2, (a2)
	 sub a2, a2, a0
	 li a1, 0
	 call my_memset

	li t0,0x800
	csrs mie,t0    

	li t0, 0x88    
    csrs mstatus, t0  

	/* Call _main */
	la t1, _image_start
	LREG t1, (t1)
	la t2, _start
	sub t0, t1, t2
	la a0, _main
	add a0, a0, t0
	jr a0
_main:
	call main
/*
 * Exception vectors.
 */
	.align 4
	.globl vectors
vectors:
	addi sp, sp, -(32 * REGSZ)

	SREG x1, 1 * REGSZ(sp)
	SREG x2, 2 * REGSZ(sp)
	SREG x3, 3 * REGSZ(sp)
	SREG x4, 4 * REGSZ(sp)
	SREG x5, 5 * REGSZ(sp)
	SREG x6, 6 * REGSZ(sp)
	SREG x7, 7 * REGSZ(sp)
	SREG x8, 8 * REGSZ(sp)
	SREG x9, 9 * REGSZ(sp)
	SREG x10, 10 * REGSZ(sp)
	SREG x11, 11 * REGSZ(sp)
	SREG x12, 12 * REGSZ(sp)
	SREG x13, 13 * REGSZ(sp)
	SREG x14, 14 * REGSZ(sp)
	SREG x15, 15 * REGSZ(sp)
	SREG x16, 16 * REGSZ(sp)
	SREG x17, 17 * REGSZ(sp)
	SREG x18, 18 * REGSZ(sp)
	SREG x19, 19 * REGSZ(sp)
	SREG x20, 20 * REGSZ(sp)
	SREG x21, 21 * REGSZ(sp)
	SREG x22, 22 * REGSZ(sp)
	SREG x23, 23 * REGSZ(sp)
	SREG x24, 24 * REGSZ(sp)
	SREG x25, 25 * REGSZ(sp)
	SREG x26, 26 * REGSZ(sp)
	SREG x27, 27 * REGSZ(sp)
	SREG x28, 28 * REGSZ(sp)
	SREG x29, 29 * REGSZ(sp)
	SREG x30, 30 * REGSZ(sp)
	SREG x31, 31 * REGSZ(sp)

	csrr a0, mcause
    csrr a1, mepc
    mv a2, sp
	call handle_trap
    csrw mepc, a0

	LREG x1, 1 * REGSZ(sp)
	LREG x2, 2 * REGSZ(sp)
	LREG x3, 3 * REGSZ(sp)
	LREG x4, 4 * REGSZ(sp)
	LREG x5, 5 * REGSZ(sp)
	LREG x6, 6 * REGSZ(sp)
	LREG x7, 7 * REGSZ(sp)
	LREG x8, 8 * REGSZ(sp)
	LREG x9, 9 * REGSZ(sp)
	LREG x10, 10 * REGSZ(sp)
	LREG x11, 11 * REGSZ(sp)
	LREG x12, 12 * REGSZ(sp)
	LREG x13, 13 * REGSZ(sp)
	LREG x14, 14 * REGSZ(sp)
	LREG x15, 15 * REGSZ(sp)
	LREG x16, 16 * REGSZ(sp)
	LREG x17, 17 * REGSZ(sp)
	LREG x18, 18 * REGSZ(sp)
	LREG x19, 19 * REGSZ(sp)
	LREG x20, 20 * REGSZ(sp)
	LREG x21, 21 * REGSZ(sp)
	LREG x22, 22 * REGSZ(sp)
	LREG x23, 23 * REGSZ(sp)
	LREG x24, 24 * REGSZ(sp)
	LREG x25, 25 * REGSZ(sp)
	LREG x26, 26 * REGSZ(sp)
	LREG x27, 27 * REGSZ(sp)
	LREG x28, 28 * REGSZ(sp)
	LREG x29, 29 * REGSZ(sp)
	LREG x30, 30 * REGSZ(sp)
	LREG x31, 31 * REGSZ(sp)
	
	addi sp, sp, (32 * REGSZ)
	mret


.weak handle_trap
handle_trap:
1:
  j 1b


/*
 * The location of section
 */
	.align 3
_image_start:
	RVPTR __image_start
_image_end:
	RVPTR __image_end
_global_pointer$:
	RVPTR __global_pointer$
_data_start:
	RVPTR __data_start
_data_end:
	RVPTR __data_end
_bss_start:
	RVPTR __bss_start
_bss_end:
	RVPTR __bss_end
_stack_start:
	RVPTR __stack_start
_stack_end:
	RVPTR __stack_end
_ddr_bin_start:
	RVPTR __ddr_bin_start
_ddr_bin_end:
	RVPTR __ddr_bin_end
